
import { IColumns, StoreFuncs, getRandomId } from "../../ExcelStore";
import $ from 'jquery';
import { get } from 'lodash';
import { dotPngImg, getInputValue, getHreflink, linkedColor } from "./FieldCellType";
const checkedDisabledPng = '';
const unCheckedDisabledPng = '';
const checkedPng = '';
const unCheckedPng = '';
const radioCheckedPng = '';
const radioUnCheckedPng = '';
export enum CheckBoxType {
    Check = 'check',
    MutilCheck = 'checkbox',
    Raido = 'radio'
};
const checkedDisabledPngImg = document.createElement("img");
checkedDisabledPngImg.src = checkedDisabledPng;
const unCheckedDisabledPngImg = document.createElement("img");
unCheckedDisabledPngImg.src = unCheckedDisabledPng;
const checkedPngImg = document.createElement("img");
checkedPngImg.src = checkedPng;
const unCheckedPngImg = document.createElement("img");
unCheckedPngImg.src = unCheckedPng;
const radioCheckedPngImg = document.createElement("img");
radioCheckedPngImg.src = radioCheckedPng;
const radioUnCheckedPngImg = document.createElement("img");
radioUnCheckedPngImg.src = radioUnCheckedPng;
export interface IOptionItem {
    value: string;
    name: string;
}
const getImg = (type: CheckBoxType, checked: boolean, editable: boolean) => {
    if (editable) {
        if (type === CheckBoxType.Raido) {
            return checked ? radioCheckedPngImg : radioUnCheckedPngImg;
        }
        return checked ? checkedPngImg : unCheckedPngImg;
    }
    if (type === CheckBoxType.Raido) {
        return checked ? radioCheckedPngImg : radioUnCheckedPngImg;
    }
    return checked ? checkedDisabledPngImg : unCheckedDisabledPngImg;
}
export default (column: IColumns, editable: boolean) => {
    class Type extends GC.Spread.Sheets.CellTypes.Base {
        checkBoxType: CheckBoxType = CheckBoxType.Check;
        _items: IOptionItem[] = [];

        _itemWidth: any = {};
        _itemSumWidth: any = {};
        startY: any = {};
        _itemsMap: any = {};
        _timer: any = {};
        constructor(checkBoxType: CheckBoxType = CheckBoxType.Check) {
            super();
            this.checkBoxType = checkBoxType;
        }
        items(items: IOptionItem[]) {
            this._items = items;
        }
        paint(ctx: CanvasRenderingContext2D, value: any, x: number, y: number, w: number, h: number, style: GC.Spread.Sheets.Style, context?: any) {
            const { row, col, sheet } = context;
            try {
                ctx.clearRect(x, y, w, h);
                ctx.font = style.font;
                delete style.vAlign;
                value = getInputValue(value);
                if (!editable && getHreflink(value)) {
                    style.foreColor = linkedColor;
                    style.textDecoration = GC.Spread.Sheets.TextDecorationType.underline;
                }
                if (this.checkBoxType === CheckBoxType.Check) {
                    if (value === '1') {
                        ctx.drawImage(getImg(this.checkBoxType, true, editable), x + 7, y + h / 2 - 7, 14, 14);
                        //  ctx.restore();
                    } else {
                        ctx.drawImage(getImg(this.checkBoxType, false, editable), x + 7, y + h / 2 - 7, 14, 14);
                        //  ctx.restore();
                    }
                } else if (this.checkBoxType === CheckBoxType.MutilCheck || this.checkBoxType === CheckBoxType.Raido) {
                    const valueArray: string[] = value ? value.split(',') : [];

                    let rowIndex = 0;
                    this._itemWidth[row] = [];
                    this._itemWidth[row][rowIndex] = [];
                    this._itemSumWidth[row] = [];
                    this._itemSumWidth[row][rowIndex] = 0;
                    this._itemsMap[row] = [];
                    this._itemsMap[row][rowIndex] = [];
                    let leftHeight = h;
                    const itemArray = this._items.map(item => {
                        const isSelected = valueArray.indexOf(item.value) > -1;
                        const textWidth = parseInt(ctx.measureText(item.name).width.toString());
                        const itemWidth = 28 + textWidth;
                        if (this._itemSumWidth[row][rowIndex] + itemWidth + 28 > w && this._itemWidth[row][rowIndex].length > 0) {
                            rowIndex++;
                            this._itemWidth[row][rowIndex] = [];
                            this._itemSumWidth[row][rowIndex] = 0;
                            this._itemsMap[row][rowIndex] = [];
                            leftHeight -= 20;
                            leftHeight = leftHeight < 0 ? 0 : leftHeight;
                        }
                        this._itemsMap[row][rowIndex].push(item);
                        const rt = {
                            ...item,
                            itemWidth,
                            rowIndex,
                            left: x + this._itemSumWidth[row][rowIndex] + 7,
                            top: y + 20 * rowIndex,
                            isSelected,
                            height: leftHeight
                        };
                        this._itemWidth[row][rowIndex].push(itemWidth);
                        this._itemSumWidth[row][rowIndex] += itemWidth + 7;
                        return rt;
                    })
                    const rowHeight = rowIndex * 20 + 20;
                    this.startY[row] = Math.max(0, (h - rowHeight) / 2);
                    itemArray.forEach(item => {
                        const { isSelected, left, top, name, height } = item;
                        super.paint(ctx, name,
                            left + 21,
                            top + this.startY[row],
                            w,
                            height,
                            style,
                            context
                        );
                        //  ctx.save();
                        ctx.drawImage(getImg(this.checkBoxType, isSelected, editable),
                            left,
                            top + this.startY[row] + 3,
                            14,
                            Math.min(height, 14)
                        );
                        //   ctx.restore();
                    });
                }
                if (editable && get(sheet.modifyedValues, `${StoreFuncs.getRandomId(row)}.${col}`)) {
                    ctx.drawImage(dotPngImg, x, y, 8, 8);
                }
            } catch (e) {
            }
        }
        getAutoFitWidth(value: any, a: string, cellStyle: GC.Spread.Sheets.Style, zoomFactor: number, context?: any): number {
            if (this.checkBoxType === CheckBoxType.Check) {
                return 28;
            }
            return Math.max(...this._items.map(d => {
                return super.getAutoFitWidth(d.name, d.name, cellStyle, zoomFactor, context) + 28;
            }));
        }
        getAutoFitHeight(value: any, text: string, cellStyle: GC.Spread.Sheets.Style, zoomFactor: number, context?: any): number {
            return this.checkBoxType === CheckBoxType.Check ? 20 : 20 * this._items.length;
        }
        processMouseUp(hitInfo: GC.Spread.Sheets.IHitTestCellTypeHitInfo): boolean {
            const { isReservedLocation, doCheck } = hitInfo as any;
            if (isReservedLocation && typeof doCheck === 'function') {
                if (editable) {
                    doCheck();
                } else {
                    const { sheet, row, col, sheetArea } = hitInfo as any;
                    const hreflink = getHreflink(sheet.getValue(row, col, sheetArea));
                    if (hreflink) {
                        (window as any).cubeOpenHreflinkFromExcel(hreflink);
                    }
                }
                return true;
            }
            return super.processMouseUp(hitInfo);
        }
        processMouseMove(hitInfo: GC.Spread.Sheets.IHitTestCellTypeHitInfo): boolean {
            const { sheet, isReservedLocation, title } = hitInfo as any;
            var div = sheet.getParent().getHost();
            var canvasId = div.id + "vp_vp";
            var canvas = $("#" + canvasId)[0];
            if (sheet && isReservedLocation) {
                canvas.style.cursor = 'pointer';
                if (title) {
                    canvas.title = title;
                }
                return true;
            } else {
                canvas.title = "";
                canvas.style.cursor = 'default';
            }
            return false;
        }
        processMouseLeave(hitInfo: GC.Spread.Sheets.IHitTestCellTypeHitInfo): boolean {
            const { sheet } = hitInfo as any;
            var div = sheet.getParent().getHost();
            var canvasId = div.id + "vp_vp";
            var canvas = $("#" + canvasId)[0];
            canvas.title = "";
            canvas.style.cursor = 'default';
            return true;
        }
        getHitInfo(x: number, y: number, cellStyle: GC.Spread.Sheets.Style, cellRect: GC.Spread.Sheets.Rect, context?: any): GC.Spread.Sheets.IHitTestCellTypeHitInfo {
            const { row, col, sheetArea, sheet } = context;
            const info = {
                x,
                y,
                row,
                col,
                cellRect,
                sheetArea,
                sheet,
            } as any;
            const changeValue = (newValue, oldValueSpan) => {
                sheet.suspendPaint();
                const hreflink = getHreflink(oldValueSpan);
                const newValueSpan = JSON.stringify({ hreflink, value: newValue });
                const dataSource = sheet.getDataSource();
                const datas = dataSource.getValue("datas");
                const data = datas[row];
                data[column.column] = newValue;
                data[`${column.column}span`] = newValueSpan;
                (sheet as any).setChangedValue(getRandomId(data), column, { sheet, row, col, newValue: newValueSpan, oldValue: oldValueSpan,time:data.time });
                sheet.resumePaint();
            }
            if (editable && this.checkBoxType === CheckBoxType.Check) {
                if (x > cellRect.x + 7 && y > cellRect.y + cellRect.height / 2 - 7 && x < cellRect.x + 21 && y < cellRect.y + cellRect.height / 2 + 7) {
                    info.isReservedLocation = true;
                    info.doCheck = () => {
                        const oldValueSpan = sheet.getValue(row, col);
                        const oldValue = getInputValue(oldValueSpan);
                        const newValue = oldValue === '1' ? '0' : '1';
                        changeValue(newValue, oldValueSpan);
                    }
                }
            } else if (this.checkBoxType === CheckBoxType.MutilCheck || this.checkBoxType === CheckBoxType.Raido) {
                const rowIndex = parseInt('' + ((y - cellRect.y - this.startY[row]) / 20));
                if (rowIndex < this._itemWidth[row].length && x < cellRect.x + this._itemSumWidth[row][rowIndex]) {
                    let startX = cellRect.x
                    const datas = this._itemsMap[row][rowIndex] || [];
                    for (let i = 0; i < datas.length; i++) {
                        if (x < startX + this._itemWidth[row][rowIndex][i]) {
                            info.isReservedLocation = true;
                            info.title = datas[i].name;
                            if (editable) {
                                info.doCheck = this.checkBoxType === CheckBoxType.MutilCheck ? () => {
                                    const oldValueSpan = sheet.getValue(row, col);
                                    const oldValue = getInputValue(oldValueSpan);
                                    let valueArray: string[] = typeof oldValue === 'string' ? oldValue.split(',') : [];
                                    const clickedValue = datas[i].value;
                                    if (valueArray.indexOf(clickedValue) > -1) {
                                        valueArray = valueArray.filter(d => d !== clickedValue)
                                    } else {
                                        valueArray.push(clickedValue);
                                    }
                                    const newValue = valueArray.join(',');
                                    changeValue(newValue, oldValueSpan);
                                } : () => {
                                    const clickedValue = datas[i].value;
                                    const oldValueSpan = sheet.getValue(row, col);
                                    changeValue(clickedValue, oldValueSpan);
                                }
                            }
                            break;
                        }
                        startX += (this._itemWidth[row][rowIndex][i]);
                    }
                }
            }
            return info;
        }
    }
    return Type;
}